#include <iostream>
#include <stdarg.h>

enum Level
{
    Info = 1,
    Fatal ,
    Warning ,
};

enum Print_File
{
    Screen = 1,
    Onefile ,
    Classfile
};

const char* _file_name = "Log.txt";

class Log 
{
    std::string level_tostring()
    {
        switch(level_)
        {
            case Info:
            return "[Info]";            
            case Fatal:
            return "[Fatal]";
            case Warning:
            return "[Warning]";
            default:
            return "[]";
        }
    }
    
    std::string time_tostring()
    {
        time_t now = time(nullptr);
        struct tm* ctime = localtime(&now);
        char buffer[1024];
        snprintf(buffer , sizeof(buffer), "[%d/%d/%d %d:%d:%d] ",ctime->tm_year + 1900 , ctime->tm_mon + 1 ,ctime->tm_mday , ctime->tm_hour ,\
        ctime->tm_min , ctime->tm_sec );
        return buffer;
    }


    void PrintScreen(const std::string& str)
    {
        std::cout << str <<std::endl;
    }

    void PrintFile(const std::string& str)
    {
        FILE* fp = fopen(_file_name , "w");
        fprintf(fp, "%s\n" ,str.c_str());
        fclose(fp);
    }
    void PrintClassfile(const std::string& str)
    {
        std::string file(_file_name);
        file += level_tostring();

        FILE* fp = fopen(file.c_str() , "w");
        fprintf(fp, "%s\n" ,str.c_str());
        fclose(fp);
    }


    void PrintLog(const std::string& all)
    {
        switch(pf_)
        {
            case Screen:
                PrintScreen(all);
            break;
        
            case Onefile:
                PrintFile(all);
            break;
            
            case Classfile:
                PrintClassfile(all);
            break;
        }
    }

public:
    Log():pf_(Screen)
    {}

    void Change_file(Print_File pf)
    {
        pf_ = pf;
    }
    
    
    void operator()(Level level , const char* format , ...)
    {
        // 将日志信息分为两个部分 : 基础部分 + 自定义部分
        level_ = level;

        // 1. 基础部分 : [Info][2025/7/25 18:31]
        std::string str_level_ = level_tostring();  
        std::string str_time_ = time_tostring();

        std::string left = str_level_ + str_time_;

        // 2. 自定义部分
        char right[2048];
        va_list s;
        va_start(s , format);
        vsnprintf(right, sizeof(right) , format ,s);
        
        // 3. 汇总
        std::string all = left + right;
        
        PrintLog(all);
    }
    

private:
    Print_File pf_;
    Level level_;
};

Log lg_;